package top.infopub.util;


import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.lang3.StringUtils;


/**
 * Double运算
 * @author Awoke
 * @version 2018年9月14日
 * @see DoubleUtils
 * @since
 */
public class DoubleUtils {

    private static final int DEF_DIV_SCALE = 10;

    public static int compareWeight(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        b1 = b1.setScale(4, BigDecimal.ROUND_HALF_UP);
        b2 = b2.setScale(4, BigDecimal.ROUND_HALF_UP);
        return b1.compareTo(b2);

    }

    public static int compareMoney(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        b1 = b1.setScale(2, BigDecimal.ROUND_HALF_UP);
        b2 = b2.setScale(2, BigDecimal.ROUND_HALF_UP);
        return b1.compareTo(b2);

    }

    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算
     */
    public static double substract(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算 
     */
    public static double substract(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     */
    public static double multiply(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供（相对）精确的除法运算,当发生除不尽的情况时
     */
    public static double divide(double v1, double v2) {
        return divide(v1, v2, DEF_DIV_SCALE);
    }

    public static double divide(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }

        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double roundMoney(double v) {

        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double roundWeight(double v) {
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static String toMoney(double amount) {
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format(amount);
    }

    /**
     * 将以元为单位的金额转换成以分为单位的金额
     * @param amount
     * @return
     */
    public static String toMinuteMoney(double amount) {
        if (compareMoney(amount, 0) == 0) {
            return "0";
        }
        DecimalFormat df = new DecimalFormat("0");
        return df.format(multiply(roundMoney(amount), 100));
    }

    /**
     * 将以元为单位的金额转换成以分为单位的金额
     * 
     * @param amount
     * @return
     */
    public static double toYuanMoney(double amount) {
        if (compareMoney(amount, 0) == 0) {
            return amount;
        }
        return roundMoney(divide(amount, 100));
    }

    /**
     * 将以元为单位的金额转换成以分为单位的金额
     * 
     * @param amount
     * @return
     */
    public static double toYuanMoney(String amount) {
        if (StringUtils.isBlank(amount)) {
            return 0;
        }
        return roundMoney(divide(Double.parseDouble(amount), 100));
    }

    /**
     * 将放大了10000倍后的利率还原成原形
     * 
     * @param rate
     * @return
     */
    public static double toRealRate(String rate) {
        if (StringUtils.isBlank(rate)) {
            return 0;
        }
        return round(divide(Double.parseDouble(rate), 10000), 5);
    }

    /**
     * 将放大了10000倍后的利率
     * 
     * @param rate
     * @return
     */
    public static String toMaxRate(double rate) {
        if (compareMoney(rate, 0) == 0) {
            return "0";
        }
        DecimalFormat df = new DecimalFormat("0");
        return df.format(multiply(roundMoney(rate), 10000));
    }

    /***
     * 是否为正整数
     */
    public static boolean isPositiveInteger(double value) {
        long a = (long)value;
        if (a != value || a < 0) {
            return false;
        }
        return true;
    }

    /***
     * 是否为正整数
     */
    public static boolean isPositiveInteger(String value) {
        double d = Double.parseDouble(value);
        long a = (long)d;
        if (a != d || a < 0) {
            return false;
        }
        return true;
    }

    /**
     * Test
     * @param args 
     * @see
     */
    public static void main(String[] args) {
        String str = DoubleUtils.toMaxRate(0.13d);
        System.out.println(str);
    }
    
}
